﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestSys.Models;
using System.Xml;
using System.Xml.Schema;
using System.IO;

namespace TestSys.Controllers
{
    public class AdminController : Controller
    {
        //
        // GET: /Admin/

        public ActionResult Index()
        {
            return View();
        }

        #region TestsPart
        public ActionResult ManageTests()
        {
            return View();
        }

        public ActionResult CreateTest(int? id)
        {
            DataManager dataManager = new DataManager();
            if (id.HasValue)
            {
                ViewBag.selCrs = dataManager.GetCourseByID(id.Value).CourseName;
            }
            return View();
        }

        [HttpPost]
        public ActionResult CreateTest(IEnumerable<HttpPostedFileBase> fileUpload)
        {
            DataManager dataManager = new DataManager();
            string schLoc = Server.MapPath("/Models/Tests/testTemplate.xsd");
            string errorLog = String.Empty;
            int counter = 0;
            admininfo currAdm = (from item in dataManager.entity.admininfo where item.generalinfo.Login == User.Identity.Name select item).FirstOrDefault();

            //verifying scheme existance
            if (!System.IO.File.Exists(schLoc))
            {
                ModelState.AddModelError("", "scheme file for xml validation not found");
                return View("CreateTest");
            }
            string path = Server.MapPath("/Models/Tests");
            //receiving and verifying course existance
            int course = Int32.Parse(Request["course"]);
            courses crs = dataManager.GetCourseByID(course);
            if (crs == null || !Directory.Exists(Path.Combine(path, crs.admininfo.generalinfo.FirstName+crs.admininfo.generalinfo.LastName,crs.CourseName)))
            {
                ModelState.AddModelError("", "course not found. Maby deleted?");
                return View("CreateTest");
            }

            if(fileUpload!=null)
                foreach (var file in fileUpload)
                {
                    if (file == null)
                    {
                        counter++;
                        continue;
                    }
                    if (file.ContentType != "text/xml")
                    {
                        ModelState.AddModelError("", String.Format("{0} file is not xml file", counter));
                        counter++;
                        continue;
                    }
                    XmlDocument xmld = new XmlDocument();
                    xmld.Schemas.Add(null, schLoc);
                    try
                    {
                        xmld.Load(file.InputStream);
                        xmld.Validate(ValidationCallBack);
                    }
                    catch
                    {
                        ModelState.AddModelError("", String.Format("could not validate {0} test", counter + 1));
                        counter++;
                        continue;
                    }
                    string filename = Path.GetFileName(file.FileName);
                    path = Path.Combine(path, crs.admininfo.generalinfo.FirstName+crs.admininfo.generalinfo.LastName,crs.CourseName);
                    if (filename != null) 
                        file.SaveAs(System.IO.Path.Combine(path, filename));
                    //dataManager.entity.tests.AddObject(new tests() { TestName = filename, TestPath = "/Models/Tests/" + crs.admininfo.generalinfo.FirstName + crs.admininfo.generalinfo.LastName + "/" + crs.CourseName + "/" + filename });
                    crs.tests.Add(new tests() { TestName = filename, TestPath = "/Models/Tests/" + crs.admininfo.generalinfo.FirstName + crs.admininfo.generalinfo.LastName + "/" + crs.CourseName + "/" + filename });
                    dataManager.entity.SaveChanges();
                    counter++;
                }
            if (ModelState.Count != 0)
                return View();
            return RedirectToAction("Index");
        }
        private void ValidationCallBack(object sender, ValidationEventArgs e) { throw new Exception(); }

        #endregion

        #region GroupsPart
        public ActionResult ManageGroups()
        {
            DataManager dataManager = new DataManager();
            var groups = from item in dataManager.entity.groups select item;
            return View(groups.ToList());
        }

        public ActionResult DeleteGroup(int? id)
        {
            if (id.HasValue)
            {
                DataManager dataManager = new DataManager();
                var group = (from item in dataManager.entity.groups where item.GroupID == id select item).FirstOrDefault();
                if (group != null)
                {
                    dataManager.entity.DeleteObject(group);
                    dataManager.entity.SaveChanges();
                }
                else
                {
                    ModelState.AddModelError("", "Group was not found");
                }
            }
            return RedirectToAction("ManageGroups");
        }

        public ActionResult CreateGroup()
        {
            return View();
        }
        
        [HttpPost]
        public ActionResult CreateGroup(groups model)
        {
            if (ModelState.IsValid)
            {
                DataManager dataManager = new DataManager();
                admininfo currAdm = (from item in dataManager.entity.admininfo where item.generalinfo.Login == User.Identity.Name select item).FirstOrDefault();
                dataManager.entity.groups.AddObject(new groups(){ GroupName = model.GroupName });
                dataManager.entity.SaveChanges();
            }
            return RedirectToAction("ManageGroups");
        }

        public ActionResult EditGroup(int? id)
        {
            if (id.HasValue)
            {
                DataManager dataManager = new DataManager();
                var group = (from item in dataManager.entity.groups where item.GroupID == id select item).FirstOrDefault();
                if (group != null)
                {
                    return View(group);
                }
                else
                {
                    ModelState.AddModelError("", "Group was not found");
                }
            }
            return RedirectToAction("ManageGroups");
        }

        [HttpPost]
        public ActionResult EditGroup(groups model)
        {
            if (ModelState.IsValid)
            {
                DataManager dataManager = new DataManager();
                groups grpToEdit = dataManager.entity.groups.Select(x => x).Where(x => x.GroupID == model.GroupID).FirstOrDefault();
                if (grpToEdit != null)
                {
                    grpToEdit.GroupName = model.GroupName;
                    dataManager.entity.SaveChanges();
                }
                else
                {
                    ModelState.AddModelError("", "Sorry but this group was not found. Maby deleted?");
                    return View(new groups());
                }
            }
            return RedirectToAction("ManageGroups");
        }
        #endregion

        public ActionResult ManageUsers()
        {
            return View();
        }

        #region CoursesPart
        public ActionResult ManageCourses()
        {
            DataManager dataManager = new DataManager();
            admininfo currAdm = (from item in dataManager.entity.admininfo where item.generalinfo.Login == User.Identity.Name select item).FirstOrDefault();
            List<CourseModel> resList = new List<CourseModel>();
            foreach (var item in currAdm.courses)
            {
                resList.Add(new CourseModel(item));
            }
            return View(resList);
        }

        //GET editing View
        public ActionResult EditCourse(int? id)
        {
            if (id.HasValue)
            {
                DataManager dataManager = new DataManager();
                var course = (from item in dataManager.entity.courses where item.CourseID == id select item).FirstOrDefault();
                if(course!=null) 
                    return View(new CourseModel(course));
                else
                    return View("ErrorPage", "course not found");
            }
            else
                return RedirectToAction("ManageCourses");
        }
        
        [HttpPost]
        public ActionResult EditCourse(CourseModel model)
        {
            if(ModelState.IsValid)
            {
                DataManager dataManager = new DataManager();
                courses crsToEdit = dataManager.entity.courses.Select(x => x).Where(x => x.CourseID == model.CourseID).FirstOrDefault();
                admininfo currAdm = dataManager.GetCurrentAdmin(User);
                string path = AppDomain.CurrentDomain.BaseDirectory;
                path = Path.Combine(path,"Models", "Tests", currAdm.generalinfo.FirstName + currAdm.generalinfo.LastName, crsToEdit.CourseName);
                if (crsToEdit != null && Directory.Exists(path))
                {
                    Directory.Move(path, path + ".temp");
                    try { Directory.Move(path + ".temp", model.CourseName); }
                    catch (Exception ex)
                    {
                        ModelState.AddModelError("", ex.Message);
                        return View();
                    }
                    crsToEdit.CourseName = model.CourseName;
                    dataManager.entity.SaveChanges(); 
                }
                else
                {
                    ModelState.AddModelError("", "Sorry but this course was not found. Maby deleted?");
                    return View();
                }
            }
            return RedirectToAction("ManageCourses");
        }

        
        [HttpPost]
        public ActionResult DeleteCourse()
        {
            int id;
            if (Int32.TryParse(Request["DestrID"], out id))
            {
                DataManager dataManager = new DataManager();
                var course = (from item in dataManager.entity.courses where item.CourseID == id select item).FirstOrDefault();
                if (course != null)
                {
                    dataManager.entity.DeleteObject(course);
                    dataManager.entity.SaveChanges();
                }
                admininfo currAdm = dataManager.GetCurrentAdmin(User);
                string path = AppDomain.CurrentDomain.BaseDirectory;
                path = Path.Combine(path, "Models", "Tests", currAdm.generalinfo.FirstName + currAdm.generalinfo.LastName, course.CourseName);
                if (Directory.Exists(path))
                    Directory.Delete(path, true);
            }
            return RedirectToAction("ManageCourses");
        }

        [HttpPost]
        public ActionResult CreateCourse(FormCollection form)
        {
            DataManager dataManager = new DataManager();
            string name = Request["NewName"].ToString();
            admininfo currAdm = (from item in dataManager.entity.admininfo where item.generalinfo.Login == User.Identity.Name select item).FirstOrDefault();
            currAdm.courses.Add(new courses { CourseName = name });
            dataManager.entity.SaveChanges();
            //adding new directory for course
            string path = AppDomain.CurrentDomain.BaseDirectory;
            path = Path.Combine(path, "Models", "Tests", currAdm.generalinfo.FirstName + currAdm.generalinfo.LastName, name);
            if (Directory.Exists(path))
                Directory.Delete(path, true);
            Directory.CreateDirectory(path);
            return RedirectToAction("ManageCourses");
        }
        #endregion
    }
}
